package us.mooresr.webtroopmanager.server.servlets;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import us.mooresr.webtroopmanager.shared.Person;
import us.mooresr.webtroopmanager.shared.PersonSummary;

import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

public class FileDownloadServlet extends HttpServlet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 910320676238535287L;
	final long MILLIS_PER_YEAR = 31536000000L;
	final long MILLIS_PER_60_DAYS = 5184000000L;
	Date oneYearAgo;
	Date soonDate;
	
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
		this.processRequest(request, response);
	}

	@Override
	public void init()	
	{
		ObjectifyService.register(Person.class);
	
	}

	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
		this.processRequest(request, response);
	}


	private void processRequest(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {

	

		String recordType = request.getParameter("recordType");
		
		ByteArrayInputStream inputStream = createCsvFile(recordType);
		
	    ServletOutputStream outputStream = response.getOutputStream();
	    response.setContentType("application/x-download");
	    response.setContentLength((int) inputStream.available());
	    response.setHeader("Content-Disposition", "attachment; filename=" + recordType + "s.csv");

	    byte[] buffer = new byte[8 * 1024]; // 8k buffer
	    int length = 0;

	    try {
	      while ((inputStream != null) && ((length = inputStream.read(buffer)) != -1)) {
	        outputStream.write(buffer, 0, length);
	      }
	    } catch (Exception e) {
	      StringWriter stringWriter = new StringWriter();
	      PrintWriter printWriter = new PrintWriter(stringWriter);
	      e.printStackTrace(printWriter);
	      response.setContentType("text/plain");
	      response.getOutputStream().print(stringWriter.toString());
	    } finally {
	      inputStream.close();
	      outputStream.flush();
	      outputStream.close();
	    }
	}



	private ByteArrayInputStream createCsvFile(String recordType) {
		StringBuffer buffer = new StringBuffer();
		Formatter formatter = new Formatter(buffer);
		Logger logger = Logger.getLogger("us.mooresr.webtroopmanager");

		
		List<Person> list = new ArrayList<Person>();
		Objectify ofy = ObjectifyService.begin();
		
		
		Query<Person> allPeople = ofy.query(Person.class).order("lastName");
		
		
		long now = System.currentTimeMillis();
		oneYearAgo = new Date(now - MILLIS_PER_YEAR);
		soonDate = new Date(now - MILLIS_PER_YEAR + MILLIS_PER_60_DAYS);
		logger.fine("MILLIS_PER_YEAR is " + MILLIS_PER_YEAR);
		logger.fine("MILLIS_PER_60_DAYS is " + MILLIS_PER_60_DAYS);
		
		
		buffer.append("First Name,Last Name,Part A (Health History),Part B(Hold Harmless),Part C(Medical Exam),Forms Missing?,Forms Expired?,Expiring soon?\n");
		

		
		for (Person p : allPeople) {
			Date medA = p.getMedFormA();
			Date medB = p.getMedFormB();
			Date medC = p.getMedFormC();
			
			formatter.format("%s,%s,", p.getFirstName(), p.getLastName());
			if (medA == null) {
				formatter.format("---,");
			} else {
				formatter.format("%tm/%<td/%<ty,", medA);
			}
			if (p.getMedFormC() == null) {
				formatter.format("---,");
			} else {
				formatter.format("%tm/%<td/%<ty,", medC);
			}
			if (medB == null) {
				formatter.format("---,");
			} else {
				formatter.format("%tm/%<td/%<ty,", p.getMedFormB());
			}
			if ((medA == null) || (medB == null) || (medC == null)) {
				formatter.format("Yes,");
			} else {
				formatter.format("No,");
			}
			
			if ((isExpired(medA)) || (isExpired(medB)) || (isExpired(medC))) {
				formatter.format("Yes,");
			} else {
				formatter.format("No,");
			}
			
			if ((expiresSoon(medA)) || (expiresSoon(medB)) || (expiresSoon(medC))) {
				formatter.format("Yes\n");
			} else {
				formatter.format("No\n");
			}
			


		}
		

		
		return new ByteArrayInputStream(buffer.toString().getBytes());
	}

	private boolean expiresSoon(Date d) {
		if (d == null) {
			return false;
		}
		if (d.before(soonDate)) {
			return true;
		}
		return false;
	}

	private boolean isExpired(Date d) {
		if (d == null) {
			return false;
		}
		if (d.before(oneYearAgo)) {
			return true;
		}
		return false;
	}
	

}
